#include "InputEventHandler.h"

#include <iostream>
#include <osgUtil/LineSegmentIntersector>
#include <sstream>
#include <osg/Vec3d>
#include <osg/io_utils>

#include "BuildingNode.h"
#include "AreaNode.h"
#include "StreetNode.h"
#include "PointOfInterestNode.h"


bool InputEventHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa, osg::Object* o, osg::NodeVisitor* nv )
{
    if(ea.getEventType() != osgGA::GUIEventAdapter::RELEASE ||
       (ea.getButton() != osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON && ea.getButton() != osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) ||
       !(ea.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_CTRL))
    {
        return false;
    }

    osgUtil::LineSegmentIntersector::Intersections intersections;

	// compute intersection of the a ray from the mouse position along the viewing direction
	if(m_viewer->getView()->computeIntersections(ea.getX(),ea.getY(),intersections))
    {
		// hitr contains all scene elements that are intersected
		osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin();

        if(ea.getButton() == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)
        {
		    if (!hitr->nodePath.empty())
		    {
			    // a node has been hit...
			    osg::Node* node = hitr->nodePath.back();
			    if(node != 0)
			    {

                    BuildingNode* buildingsNode = NULL;
                    AreaNode* areaNode = NULL;
                    StreetNode* streetNode = NULL;

                    buildingsNode = dynamic_cast<BuildingNode*>(node);
                    if(buildingsNode)
                    {
                        highlightGeode(buildingsNode);
                        emit sendFeatureInfo(buildingsNode->getFeatureString());
                    }
                    else
                    {
                        areaNode = dynamic_cast<AreaNode*>(node);
                        if(areaNode)
                        {
                            highlightGeode(areaNode);
                            emit sendFeatureInfo(areaNode->getFeatureString());
                        }
                        else
                        {
                            streetNode = dynamic_cast<StreetNode*>(node);
                            if(streetNode)
                            {
                                highlightGeode(streetNode);
                                emit sendFeatureInfo(streetNode->getFeatureString());
                            }
                        }
                    }
                        
			    }
		    }
		    else if (hitr->drawable.valid())
		    {
                // oO
		    }
        }
        else if(ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
        {
            // Hitpoint in World Coordinates
            osg::Vec3 hitPoint = hitr->getWorldIntersectPoint();
            emit sendMarkerPosition(&hitPoint);
	    }
    }

    return false;
}

void InputEventHandler::highlightGeode(ToggleNode* geode)
{
    if(!m_prevHighlightedGeode)
    {
        m_prevHighlightedGeode = geode;
        geode->toggleHightlight();
        return;
    }

    if(m_prevHighlightedGeode == geode)
    {
        geode->toggleHightlight();
        return;
    }
    else
    {
        m_prevHighlightedGeode->resetColor();
        geode->toggleHightlight();
        m_prevHighlightedGeode = geode;
    }
}

InputEventHandler::InputEventHandler(QtViewer* viewer):
m_viewer(viewer),
m_prevHighlightedGeode(NULL)
{
    connect(this, SIGNAL(sendFeatureInfo(QString)), viewer, SLOT(onIntersectionInfo(QString)));
    connect(this, SIGNAL(sendMarkerPosition(osg::Vec3*)), viewer, SLOT(onSetMarker(osg::Vec3*)));
}